import {
	BASE_URL
} from '@/config/index.js';

function getToken() {
	return uni.getStorageSync('accessToken');
}

function setToken(token) {
	uni.setStorageSync('accessToken', token);
}

const apiSuccessStatus = 200;

let requestQueue = [];
let isRefreshingToken = false; // 用于防止重复刷新token
let refreshTokenPromise = null; // 缓存token刷新的Promise

// 封装请求函数
function request(url, options = {}) {
	return new Promise((resolve, reject) => {
		const token = getToken();
		if (token) {
			options.header = {
				// ... 其他头部信息
				Authorization: `Bearer ${token}`
			};
		}

		// 加载
		const load = () => (options.method === 'post' ||
			options.method === 'put' ||
			options.method === 'delete')

		if (load()) {
			uni.showLoading({
				title: '稍等片刻...',
				mask: true
			});
		}

		// 发起请求
		uni.request({
			url: BASE_URL + url,
			...options,
			success: (res) => {
				if (load()) uni.hideLoading();
				// 从队列中移除请求、登录过期
				if (res.data.status === 401) {
					// 提示用户登录过期或者权限不足
					setTimeout(() => {
						uni.showToast({
							title: '登录过期，请重新登录', // 提示信息
							icon: 'none',
							duration: 3000
						});
					}, 1800); // 延迟1.5秒
					
					// 清除本地存储并跳转到登录页面
					uni.clearStorageSync();
					uni.setStorageSync('notLogin', true);

					// 重定向到登录页面
					return uni.reLaunch({
						url: '/pages/main/index'
					});
				}
				// 特定放开条件和请求正常
				else if (
					options?.data?.unblocked ||
					res.data.status === apiSuccessStatus
				) {
					removeRequestFromQueue(url);
					resolve(res.data);
				} else {
					removeRequestFromQueue(url);
					setTimeout(() => {
						uni.showToast({
							title: res.data.msg,
							icon: 'none',
							duration: 3000
						});
					}, 0);
					reject(res.data)
				}
			},
			fail: (err) => {
				if (load()) uni.hideLoading();
				if (err.errMsg === 'request:fail timeout') {
					uni.showToast({
						title: '请求超时，请刷新后重试',
						icon: 'none',
						mask: true,
						duration: 3000
					});
				} else {
					reject(err);
					uni.showToast({
						title: '请求服务器失败，请稍后重试',
						icon: 'none',
						mask: true,
						duration: 3000
					});
				}
			}
		});
	});
}

// 添加到请求队列
function addToRequestQueue(url, options, resolve, reject) {
	requestQueue.push({
		url,
		options,
		resolve,
		reject
	});
}

// 从请求队列中移除请求
function removeRequestFromQueue(url) {
	requestQueue = requestQueue.filter((queuedReq) => queuedReq.url !== url);
}

// 刷新token
function refreshToken() {
	console.log(isRefreshingToken);
	if (!isRefreshingToken) {
		isRefreshingToken = true;
		refreshTokenPromise = new Promise((resolve, reject) => {
			let refreshToken = uni.getStorageSync('refreshToken');
			if (!refreshToken) {
				// 清空
				uni.clearStorageSync();
				return
			}

			let refreshTokenUrl = '/app-api/member/auth/refresh-token';

			// 发送刷新token的请求到后端
			uni.request({
				url: BASE_URL + refreshTokenUrl + '?refreshToken=' + refreshToken, // 刷新token的URL
				method: 'POST', // 通常使用POST请求刷新token
				success: (res) => {
					if (res.data.status === 400 || res.data.status === 401) {
						// 清空
						uni.clearStorageSync();

						// 赋值当前路径
						const pages = getCurrentPages(); // 获取页面栈
						const currentPage = pages[pages.length - 1]; // 获取当前页面对象
						uni.setStorageSync('currentPage', currentPage.route);

						return uni.reLaunch({
							url: '/pages/main/index'
						});
					}
					uni.setStorageSync('refreshToken', res.data.data.refreshToken);
					const newToken = res.data.data.accessToken; // 假设你得到了新的token
					setToken(newToken); // 存储新的token
					resolve(newToken);
				},
				fail: (err) => {
					reject(err);
				}
			});
		});
	}
	return refreshTokenPromise;
}

// 重试请求队列中的所有请求
function retryRequests() {
	requestQueue.forEach((queuedReq) => {
		// 使用新的token重新发起请求
		request(queuedReq.url, queuedReq.options)
			.then((data) => {
				queuedReq.resolve(data);
			})
			.catch((err) => {
				queuedReq.reject(err);
			});
		// 移除已重试的请求
		removeRequestFromQueue(queuedReq.url);
	});
}

// 拒绝请求队列中的所有请求
function rejectAllRequestsInQueue(err) {
	requestQueue.forEach((queuedReq) => {
		queuedReq.reject(err);
	});
	// 清空队列
	requestQueue = [];
}

export default request;